.org 000h;
.map STACK_ADDR, 3071;
.map Display, 3074;
.map Keyboard, 3074;
.map DisplayRow, 3072;
.map RowData, 3073;
.map JSRight, 3072;
.map JSDown, 3073;
.map Rand, 3075;
.map Seconds, 3078;
.map Minutes, 3077;
.map Hours, 3076;
.map RollLeft, 3079;
.map RollRight, 3080;
.map Buttons, 3081;
.map Cartridge, 3075;
.map VideoBuffer, 1025;
.map Video_Row0, 1025;
.map Video_Row1, 1026;
.map Video_Row2, 1027;
.map Video_Row3, 1028;
.map Video_Row4, 1029;
.map Video_Row5, 1030;
.map Video_Row6, 1031;
.map Video_Row7, 1032;
.map Video_Row8, 1033;
.map Video_Row9, 1034;
.map Video_Row10, 1035;
.map Video_Row11, 1036;
.map Video_Row12, 1037;
.map Video_Row13, 1038;
.map Video_Row14, 1039;
.map Video_Row15, 1040;
.map Prompt, 1041;
.map Asterisk, 1044;
.map Colon, 1046;
.map NewLine, 1048;
.map ClearScreen, 1049;
.map InputBuffer, 1050;
.map InputLength, 1081;
.map Username, 1082;
.map UsernameEnd, 1087;
.map Password, 1087;
.map PasswordEnd, 1092;
.map ASCII_NumOffset, 1092;
.map SecondsVar, 1093;
.map MinutesVar, 1094;
.map HoursVar, 1095;
.map NumCommands, 1096;
.map UsernameLength, 1097;
.map PasswordLength, 1098;
.map KEY_Enter, 1099;
.map KEY_Backspace, 1100;
.map BTN_Quit, 1101;
.map BTN_Previous, 1102;
.map BTN_Next, 1103;
.map BTN_Select, 1104;
.map BTN_Yes, 1105;
.map BTN_No, 1106;
.map CMD_Time, 1107;
.map CMD_Rand, 1112;
.map CMD_Clear, 1117;
.map CMD_Halt, 1123;
.map CMD_Echo, 1128;
.map CMD_Load, 1133;
.map Commands, 1138;
.map Functions, 1144;
.map Lengths, 1150;
.map PrintLine, 1156;
.map PrintLineRet, 1157;
.map OrigPrintLineLoad, 1158;
.map OrigPrintLineJump, 1159;
.map PrintLineInit, 1160;
.map PrintLineLoop, 1169;
.map PrintLineDone, 1176;
.map Print, 1179;
.map PrintRet, 1180;
.map OrigPrintLoad, 1181;
.map PrintInit, 1182;
.map PrintLoop, 1191;
.map PrintDone, 1198;
.map Boot, 1199;
.map Boot_BootMSG, 1200;
.map Boot_CommandsAddr, 1220;
.map Boot_UsernameAddr, 1221;
.map Boot_PasswordAddr, 1222;
.map BootInit, 1223;
.map BootSetNumCommands, 1223;
.map BootSetUsernameLength, 1226;
.map BootSetPasswordLength, 1230;
.map BootMessage, 1234;
.map BootDone, 1245;
.map Login, 1250;
.map LoginRet, 1251;
.map Login_UsernameMSG, 1252;
.map Login_PasswordMSG, 1263;
.map Login_WelcomeMSG, 1274;
.map Login_FailedMSG, 1300;
.map Login_TempKeyboardInput, 1330;
.map Login_UsernameBuffer, 1331;
.map Login_PasswordBuffer, 1342;
.map Login_CurInputLength, 1353;
.map LoginInit, 1354;
.map LoginUsernamePrompt, 1362;
.map LoginUsernameFetchLoop, 1375;
.map LoginUsernameSaveIndex, 1387;
.map LoginPasswordPrompt, 1394;
.map LoginPasswordFetchLoop, 1409;
.map LoginPasswordSaveIndex, 1421;
.map LoginCheckUsername, 1428;
.map LoginCheckUsernameLoop, 1428;
.map LoginCheckUsernameLoopIndex, 1428;
.map LoginCheckUsernameLoopIndex2, 1430;
.map LoginCheckUsernameLoopContunue, 1433;
.map LoginCheckPassword, 1440;
.map LoginCheckPasswordLoop, 1440;
.map LoginCheckPasswordLoopIndex, 1440;
.map LoginCheckPasswordLoopIndex2, 1442;
.map LoginCheckPasswordLoopContunue, 1445;
.map LoginSuccess, 1452;
.map LoginFailure, 1477;
.map LoginDone, 1523;
.map Erase, 1524;
.map EraseRet, 1525;
.map EraseCountdown, 1526;
.map ErasePlainStore, 1527;
.map EraseInit, 1528;
.map EraseLoop, 1541;
.map EraseStoreIndex, 1544;
.map EraseDone, 1552;
.map PrintNumber, 1553;
.map PrintNumberRet, 1554;
.map PrintNumber_HexNumber, 1555;
.map PrintNumber_Places, 1556;
.map PrintNumber_DigitTimes, 1562;
.map PrintNumber_PlainPlaceIndex, 1563;
.map PrintNumber_Place, 1564;
.map PrintNumber_TempChar, 1565;
.map PrintNumber_HadNonZero, 1566;
.map PrintNumberInit, 1567;
.map PrintNumberLoop, 1583;
.map PrintNumberPlaceIndex, 1584;
.map PrintNumberNextPlace, 1591;
.map PrintNumberNextPlaceSkipNonZero, 1600;
.map PrintNumberNextPlaceSkipDisplay, 1603;
.map PrintNumberDisplay, 1614;
.map PrintNumberDisplayLoop, 1616;
.map PrintNumberDone, 1626;
.map Multiply, 1627;
.map MultiplyRet, 1628;
.map Multiply_Number1, 1629;
.map Multiply_Number2, 1630;
.map Multiply_Product, 1631;
.map MultiplyInit, 1632;
.map MultiplyLoop, 1646;
.map MultiplyDone, 1655;
.map PadNumber, 1661;
.map PadNumberRet, 1662;
.map PadNumber_Number, 1663;
.map PadNumber_Padding, 1664;
.map PadNumber_Places, 1665;
.map PadNumber_Place, 1671;
.map PadNumber_PlainSub, 1672;
.map PadNumberInit, 1673;
.map PadNumberLoop, 1694;
.map PadNumberSubIndex, 1695;
.map PadNumberLoopLessThan, 1698;
.map PadNumberLoopContinue, 1700;
.map PadNumberDone, 1708;
.map PrintTime, 1709;
.map PrintTime_Seconds, 1710;
.map PrintTime_Minutes, 1711;
.map PrintTime_Hours, 1712;
.map PrintTimeInit, 1713;
.map PrintTimeGet, 1713;
.map PrintTimeHours, 1719;
.map PrintTimeMinutes, 1748;
.map PrintTimeSeconds, 1777;
.map PrintTimeDone, 1804;
.map FetchCommand, 1809;
.map FetchCommand_PlainStore, 1810;
.map FetchCommand_TempChar, 1811;
.map FetchCommand_CharsLeft, 1812;
.map FetchCommand_MaxChars, 1813;
.map FetchCommand_Two, 1814;
.map FetchCommand_AbortWrite, 1815;
.map FetchCommandInit, 1816;
.map FetchCommandPrompt, 1822;
.map FetchCommandInputLoop, 1833;
.map FetchCommandBackspace, 1844;
.map FetchCommandSkipBackspace, 1859;
.map FetchCommandStoreIndex, 1867;
.map FetchCommandDone, 1876;
.map RunCommand, 1883;
.map RunCommandRet, 1884;
.map RunCommand_NumCommands, 1885;
.map RunCommand_BlankLoad, 1886;
.map RunCommand_BlankJumpI, 1887;
.map RunCommand_UnknownCommand, 1888;
.map RunCommandInit, 1906;
.map RunCommandLoop, 1922;
.map RunCommandCommandIndex, 1922;
.map RunCommandLengthIndex, 1927;
.map RunCommandExec, 1956;
.map RunCommandFunctionIndex, 1961;
.map RunCommandDone, 1962;
.map IsCommand, 1985;
.map IsCommandRet, 1986;
.map IsCommand_PlainLoad, 1987;
.map IsCommand_PlainXOR, 1988;
.map IsCommand_TempChar, 1989;
.map IsCommand_CMDLength, 1990;
.map IsCommandInit, 1991;
.map IsCommandLoop, 2006;
.map IsCommandLoadIndex, 2006;
.map IsCommandXORIndex, 2008;
.map IsCommandSame, 2011;
.map IsCommandExec, 2022;
.map IsCommandDone, 2028;
.map ExecTime, 2034;
.map ExecTime_TimeMSG, 2035;
.map ExecTimePrintMessage, 2056;
.map ExecTimePrintTime, 2067;
.map ExecTimeDone, 2075;
.map ExecRand, 2080;
.map ExecRandPrintNumber, 2080;
.map ExecRandDone, 2093;
.map ExecClear, 2098;
.map ExecClearClearScreen, 2098;
.map ExecClearDone, 2100;
.map ExecHalt, 2105;
.map ExecHalt_HaltMSG, 2106;
.map ExecHaltInit, 2114;
.map ExecHaltHalt, 2125;
.map ExecHaltDone, 2126;
.map ExecEcho, 2131;
.map ExecEcho_Offset, 2132;
.map ExecEchoInit, 2133;
.map ExecEchoDone, 2145;
.map Load, 2150;
.map Load_PlainStore, 2151;
.map Load_WordsLeft, 2152;
.map Load_LoadMessage, 2153;
.map Load_LoadMessage2, 2163;
.map Load_FinishedMSG, 2190;
.map Load_CurAddress, 2216;
.map Load_24, 2217;
.map LoadInit, 2218;
.map LoadTitleLoop, 2240;
.map LoadTitle2, 2251;
.map LoadLoop, 2264;
.map LoadStoreIndex, 2269;
.map LoadFinished, 2278;
.map LoadExec, 2289;
.map LoadDone, 2295;
.map UpdateVideo, 2300;
.map UpdateVideo_PlainLoad, 2301;
.map UpdateVideo_LoopsLeft, 2302;
.map UpdateVideo_VideoAddr, 2303;
.map UpdateVideoInit, 2304;
.map UpdateVideoLoop, 2310;
.map UpdateVideoLoadIndex, 2312;
.map UpdateVideoDone, 2325;
.map StoreBuffer, 2330;
.map StoreBufferRet, 2331;
.map StoreBuffer_PlainLoad, 2332;
.map StoreBuffer_PlainStore, 2333;
.map StoreBuffer_LoopsLeft, 2334;
.map StoreBufferInit, 2335;
.map StoreBufferLoop, 2348;
.map StoreBufferLoadIndex, 2348;
.map StoreBufferStoreIndex, 2349;
.map StoreBufferDone, 2361;
.map PromptYesNo, 2362;
.map PromptYesNoRet, 2363;
.map PromptYesNo_ButtonState, 2364;
.map PromptYesNoInit, 2365;
.map PromptYesNoLoop, 2375;
.map PromptYesNoDoYes, 2383;
.map PromptYesNoDoNo, 2389;
.map PromptYesNoDone, 2395;
.map Start, 2396;
.map LoopStart, 2408;
.map EndLoop, 2437;
.map One, 2438;
.map PushData, 2439;
.map StackReturn, 2440;
.map SPush, 2441;
.map PushAddr, 2442;
.map SPop, 2451;
.map PopAddr, 2457;
.map RetAddress, 2459;
.map PlainJump, 2460;
.map STACK_ADDR, 3071;
	
.word 0(ProgramEnd); Program length
.string "Space Invaders"; Program Title
.org 001h;

	ProgramStart:
			JMP (AppInit);
				App_LaunchMSG1:
					.string "Welcome to Space Invaders!";
				App_LaunchMSG2:
					.string "Loading...";
				App_DoneLoadingMSG1:
					.string "Done!";
				App_DoneLoadingMSG2:
					.string "Press QUIT to quit the game";
				App_QuitPromptMSG:
					.string "Are you sure you would like to quit?";
				App_QuitMSG:
					.string "Goodbye!";
				App_StartDisplay:
					.word 0000h, 0000h, 0000h, 0000h, 0000h, 0000h, 0000h, 0000h, 0000h, 0000h, 0000h, 0000h, 0000h, 0080h, 01C0h, 0000h; Starting display
				App_JSRightState:
					.word 0000h;
				App_Left:
					.word 0001h;
				App_Right:
					.word 0003h;
				App_RefreshDisplay:
					.word 0001h;
			AppInit:
				LDI (App_LaunchMSG1);
				PUSH;
				CALL (PrintLine);
				LDI (App_LaunchMSG2);
				PUSH;
				CALL (PrintLine);
				LDI (App_StartDisplay); Load pointer to start image
				CALL (StoreBuffer); Send the start screen to video buffer
				CALL (UpdateVideo); Update display
				LDI (App_DoneLoadingMSG1);
				PUSH;
				CALL (PrintLine);
				LDI (App_DoneLoadingMSG2);
				PUSH;
				CALL (PrintLine);
			AppLoop:
				LDI 1;
				STM (App_RefreshDisplay);
				AppTestQuit:
					LDM (Buttons);
					XOR (BTN_Quit);
					JPZ (AppAskQuit);
					AppTestQuitRet:
				AppGetJSState:
					LDM (JSRight);
					STM (App_JSRightState);
					XOR (App_Left);
					JPZ (AppMoveLeft);
					AppMoveLeftRet:
					LDM (App_JSRightState);
					XOR (App_Right);
					JPZ (AppMoveRight);
					AppMoveRightRet:
				AppLoopDone:
					JPZ (App_RefreshDisplay);
					JMP (AppLoop);
				AppUpdateDisplay:
					CALL (UpdateVideo); Update display
					JMP (AppLoopDone);
			AppMoveLeft:
				LDM (Video_Row13);
				STM (RollLeft);
				LDM (RollLeft);
				STM (Video_Row13);
				LDM (Video_Row14);
				STM (RollLeft);
				LDM (RollLeft);
				STM (Video_Row14);
				LDI 13;
				STM (DisplayRow);
				LDM (Video_Row13);
				STM (RowData);
				LDI 14;
				STM (DisplayRow);
				LDM (Video_Row14);
				STM (RowData);
				JMP (AppMoveLeftRet);
			AppMoveRight:
				LDM (Video_Row13);
				STM (RollRight);
				LDM (RollRight);
				STM (Video_Row13);
				LDM (Video_Row14);
				STM (RollRight);
				LDM (RollRight);
				STM (Video_Row14);
				LDI 13;
				STM (DisplayRow);
				LDM (Video_Row13);
				STM (RowData);
				LDI 14;
				STM (DisplayRow);
				LDM (Video_Row14);
				STM (RowData);
				JMP (AppMoveRightRet);
			AppAskQuit:
				LDI (App_QuitPromptMSG);
				PUSH;
				CALL (PromptYesNo);
				POP; Pop result
				JPZ (AppDone);
				JMP (AppTestQuitRet);
			AppDone:
				; Display quit message
				LDI (App_QuitMSG);
				PUSH;
				CALL (PrintLine);
				; Erase video display
				LDI (VideoBuffer);
				PUSH;
				LDI 16;
				PUSH;
				CALL (Erase);
				CALL (UpdateVideo);
				; Clear terminal
				LDM (ClearScreen);
				STM (Display);
				RET; Return to DrewOS
ProgramEnd: